package com.xw.tools.view;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.TextArea;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;

import java.math.BigDecimal;

public class DDLCreateTableWin extends AbstractWin {

    private Button button = new Button("生成");

    private TextArea outputTextArea;

    private TextArea inputTextArea;


    private ChoiceBox cb;

    private void start() {
        Stage stage = new Stage();
        stage.setTitle("创建表");
        //stage.initModality(Modality.WINDOW_MODAL);
        //stage.initOwner(primaryStage);
        Scene scene = new Scene(new VBox(), 800, 495);
        initView(scene);
        stage.setScene(scene);
        stage.show();
    }

    private void initView(Scene scene) {
        inputTextArea = new TextArea();
        inputTextArea.setFont(Font.font(16));
        inputTextArea.setText("{\n" +
                "\t\"@table\":\"test_user\",\n" +
                "\t\"id\":1,\n" +
                "\t\"name\":\"zs\",\n" +
                "\t\"age\":23,\n" +
                "\t\"score\":1.23,\n" +
                "\t\"createTime\":\"datetime\"\n" +
                "}\n");
        cb = new ChoiceBox(FXCollections.observableArrayList(
                "Json", "Markdown")
        );
        cb.setValue("Json");
        cb.setOnAction(event -> {
            String value = (String) cb.getValue();
            if ("Markdown".equals(value)) {
                inputTextArea.setText("### user 用户表\n" +
                        "| 列名 | 类型        | 不是Null | 主键 | 注释   |\n" +
                        "| ---- | ----------- | ------- | ---- | ------ |\n" +
                        "| id   | int         | Y        | Y    | 主键ID |\n" +
                        "| name | varchar(64) | Y        | N    | 姓名   |\n" +
                        "| age  | int         | Y        | N    | 年龄   |\n");
            }
            if ("Json".equals(value)) {
                inputTextArea.setText("{\n" +
                        "\t\"@table\":\"test_user\",\n" +
                        "\t\"id\":1,\n" +
                        "\t\"name\":\"zs\",\n" +
                        "\t\"age\":23,\n" +
                        "\t\"score\":1.23,\n" +
                        "\t\"createTime\":\"datetime\"\n" +
                        "}\n");
            }
        });

        outputTextArea = new TextArea();
        outputTextArea.setFont(Font.font(16));
        outputTextArea.setEditable(false);
        button.setOnAction((ActionEvent t) -> {
            String text = inputTextArea.getText();
            if (StrUtil.isBlank(text)) {
                return;
            }
            String value = (String) cb.getValue();
            if ("Markdown".equals(value)) {
                String[] lines = text.split("\n");
                String tableName = lines[0].split(" ")[1];
                String tableComment = lines[0].split(" ")[2];
                StringBuilder sb = new StringBuilder("CREATE TABLE ");
                sb.append(tableName);
                sb.append(" (\n");
                String pk = "";
                for (int i = 3; i < lines.length; i++) {
                    if (StrUtil.isBlank(lines[i])) {
                        continue;
                    }
                    String[] cs = lines[i].split("\\|");
                    String columnName = StrUtil.trim(cs[1]);
                    String columnType = StrUtil.trim(cs[2]);
                    String isNullFlag = StrUtil.trim(cs[3]);
                    String isPkFlag = StrUtil.trim(cs[4]);
                    String columnComment = StrUtil.trim(cs[5]);
                    if ("".equals(pk) && "Y".equals(isPkFlag)) {
                        pk = columnName;
                    }
                    sb.append("    ");
                    sb.append(columnName);
                    sb.append(" " + columnType + " ");
                    if ("Y".equals(isNullFlag)) {
                        sb.append("NOT NULL ");
                    } else {
                        sb.append(" NULL ");
                    }
                    if ("id".equalsIgnoreCase(columnName) && "Y".equals(isPkFlag)) {
                        sb.append("AUTO_INCREMENT ");
                    }
                    if (StrUtil.isNotBlank(columnComment)) {
                        sb.append("COMMENT '" + columnComment + "',");
                    }
                    sb.append("\n");
                }
                if (StrUtil.isNotBlank(pk)) {
                    sb.append("    PRIMARY KEY (" + pk + ")\n");
                } else {
                    sb.deleteCharAt(sb.lastIndexOf(","));
                }
                sb.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='" + tableComment + "';");
                outputTextArea.setText(sb.toString());
            }
            if ("Json".equals(value)) {
                JSONObject jsonObject = JSONUtil.parseObj(text, false, true);
                if (jsonObject == null) {
                    outputTextArea.setText("json parse error!");
                    return;
                }

                String table = jsonObject.getStr("@table");
                if (StrUtil.isNotBlank(table)) {
                    jsonObject.remove("@table");
                } else {
                    table = "temp_table";
                }
                StringBuilder sb = new StringBuilder("CREATE TABLE " + table + " (\n");
                String pk = "";
                for (String key : jsonObject.keySet()) {
                    String type = getTypeFromObj(jsonObject.get(key));
                    key = StrUtil.toUnderlineCase(key);
                    sb.append("    " + key + " ");
                    sb.append(type);
                    if ("id".equalsIgnoreCase(key) && type.startsWith("int")) {
                        sb.append(" NOT NULL AUTO_INCREMENT COMMENT 'ID',\n");
                        pk = key;
                    } else {
                        sb.append(" NULL COMMENT '" + key + "',\n");
                    }
                }
                if (StrUtil.isNotBlank(pk)) {
                    sb.append("    PRIMARY KEY (" + pk + ")\n");
                } else {
                    sb.deleteCharAt(sb.lastIndexOf(","));
                }
                sb.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='" + table + "';");
                outputTextArea.setText(sb.toString());
            }
        });
        VBox box = (VBox) scene.getRoot();
        box.getChildren().add(inputTextArea);
        box.getChildren().add(cb);
        box.getChildren().add(button);
        box.getChildren().add(outputTextArea);
        VBox.setVgrow(inputTextArea,  Priority.ALWAYS);
        VBox.setVgrow(outputTextArea,  Priority.ALWAYS);
    }

    private String getTypeFromObj(Object obj) {
        if (obj == null) {
            return "varchar(256)";
        }
        if (obj instanceof String && "datetime".equals(obj)) {
            return "datetime";
        }
        if (obj instanceof String) {
            return "varchar(256)";
        }
        if (obj instanceof Integer) {
            return "int(11)";
        }
        if (obj instanceof Boolean) {
            return "int(2)";
        }
        if (obj instanceof BigDecimal) {
            BigDecimal bigDecimal = (BigDecimal) obj;
            return "decimal(8, " + bigDecimal.scale() + ")";
        }

        return "varchar(256)";
    }

    @Override
    public void show() {
        start();
    }
}
